package com.design.reactor.stretchIO._2_singleReactorMultiThread;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

public class Reactor2  implements Runnable{
	final Selector selector;
    final ServerSocketChannel serverSocketChannel;

    /**
     * reactor 1: 初始设置
     */
    Reactor2(int port) throws IOException {
        selector = Selector.open();
        serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.socket().bind(new InetSocketAddress(port));
        serverSocketChannel.configureBlocking(false);
        SelectionKey sk = serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        Acceptor acceptor= new Acceptor();
        sk.attach(acceptor);//绑定数据
        System.out.println("----Reactor 构造函数 中ServerSocketChannel  SelectionKey ： " + sk);
        System.out.println("----Reactor 构造函数 中绑定的 对象   acceptor ： " + acceptor);
    }
    /**
     * reactor 2: 分发循环
     */
    @Override
    public void run() {
        try {
        	System.out.println("----当前线程名 ："+Thread.currentThread().getName());
            while (!Thread.interrupted()) {
                selector.select();//获取注册事件
                Set<SelectionKey> sks = selector.selectedKeys();
                for (SelectionKey sk : sks) {
                    dispatcher(sk);//分发每一个请求
                }
                // 也可以在while循环中使用iterator的remove方法
                sks.clear();
            }
        } catch (IOException ignored) {
            // ignored
        }
    }

    private void dispatcher(SelectionKey sk) {
        Runnable r = (Runnable) sk.attachment();//获取之前绑定的对象
        System.out.println("----Reactor  dispatcher(SelectionKey sk) 中  SelectionKey ： " + sk);
        System.out.println("----Reactor  dispatcher(SelectionKey sk) 中  获得的acceptor ： " + r);
        if (null != r) {
            r.run();
        }
    }
    //Acceport也是处理器EventHandler的一种, 用于处理socket accept事件
    class Acceptor implements Runnable {
        @Override
        public void run() {
            try {
            	System.out.println("----当前线程名 ："+Thread.currentThread().getName());
                SocketChannel c = serverSocketChannel.accept();
                System.out.println("----Acceptor  run() 中  获得的客户端SocketChannel ： " + c);
                if (null != c) {
                    new Handler2(selector, c);
                }
            } catch (IOException ignored) {
                // ignored
            }
        }
    }
    public static void main(String[] args) throws Exception {
    	Reactor2 reactor= new Reactor2(8899);
    	new Thread(reactor).start();//这就是 reactor 线程 服务端线程
	}
}
